{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Training the cost model with a ranking loss"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "from os import environ\n",
    "environ['train_device'] = 'cuda:1' # training device: 'cpu' or 'cuda:X'\n",
    "environ['store_device'] = 'cuda:1' # Data storing device:  'cpu' or 'cuda:X'\n",
    "environ['dataset_file'] = '/data/scratch/mmerouani/processed_datasets/dataset_batch4X_train_val_set.pkl' #training / validation set\n",
    "environ['test_dataset_file'] = '/data/scratch/mmerouani/processed_datasets/dataset_batch4X_test_set.pkl' #test set\n",
    "environ['benchmark_dataset_file']='/data/scratch/mmerouani/processed_datasets/dataset_Benchmark_batch10.pkl' #benchmarks set \n",
    "#a copy of these datasets can be found in /data/commit/tiramisu/cost-model_datasets/processed_datasets/\n",
    "\n",
    "%run utils.py # imports and defines some utils functions"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Data loading"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "loading batches from: /data/scratch/mmerouani/processed_datasets/dataset_batch4X_train_val_set.pkl\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████| 46640/46640 [27:29<00:00, 28.27it/s]   \n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "GPU memory on cuda:1 nearly full, switching to CPU memory\n",
      "Number of meta batches 46640\n",
      "Data loaded\n",
      "Sizes: (9328, 37312) batches\n",
      "loading batches from: /data/scratch/mmerouani/processed_datasets/dataset_batch4X_test_set.pkl\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████| 8502/8502 [06:00<00:00, 23.55it/s]  \n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "GPU memory on cuda:1 nearly full, switching to CPU memory\n",
      "Number of meta batches 8502\n",
      "Data loaded\n",
      "Sizes: (8502, 0) batches\n"
     ]
    }
   ],
   "source": [
    "train_val_dataset, val_bl, val_indices, train_bl, train_indices = load_data_meta_batches(dataset_file, 0.2, max_batch_size=832)\n",
    "test_dataset, test_bl, test_indices, _, _ = load_data_meta_batches(test_dataset_file, 1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Model definition "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "input_size = 2534\n",
    "\n",
    "criterion = ndcgLoss2PP_meta_batches # Using nDCG-Loss-2++\n",
    "\n",
    "model = None \n",
    "model = Model_Recursive_LSTM_v2_ranking(input_size, drops=[0.112, 0.112, 0.112, 0.112])\n",
    "model.to(train_device)\n",
    "\n",
    "optimizer = AdamW(model.parameters(),weight_decay=0.375e-2)    \n",
    "    "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Model training"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 1/800:  train Loss: 11.1857   val Loss: 8.1448   time: 1209.35s   best loss: 8.1448\n",
      "Epoch 2/800:  train Loss: 8.4159   val Loss: 7.6152   time: 1214.85s   best loss: 7.6152\n",
      "Epoch 3/800:  train Loss: 7.9054   val Loss: 7.3919   time: 1247.45s   best loss: 7.3919\n",
      "Epoch 4/800:  train Loss: 7.6130   val Loss: 7.1376   time: 1225.39s   best loss: 7.1376\n",
      "Epoch 5/800:  train Loss: 7.4745   val Loss: 6.9653   time: 1236.47s   best loss: 6.9653\n"
     ]
    },
    {
     "ename": "KeyboardInterrupt",
     "evalue": "",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mKeyboardInterrupt\u001b[0m: "
     ]
    }
   ],
   "source": [
    "bl_dict={'train':train_bl, 'val':val_bl}\n",
    "log_file = 'log_Recursive_LSTM_v2_ranking.txt'\n",
    "\n",
    "losses, best_model = train_model_meta_batches(model, criterion, optimizer , max_lr=0.002, dataloader=bl_dict, num_epochs=800, \n",
    "                                 logFile=log_file, log_every=1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Loading a pre-trained model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    }
   ],
   "source": [
    "model.load_state_dict(torch.load('Recursive_LSTM_v2_ndcgLoss2PP.pkl',map_location=train_device))\n",
    "model.to(train_device)\n",
    "print()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Basic results on the test set\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████| 8502/8502 [01:11<00:00, 118.40it/s]\n",
      "100%|██████████| 8502/8502 [05:28<00:00, 25.91it/s]\n"
     ]
    }
   ],
   "source": [
    "test_df, test_df_rank_scores = get_results_df_meta_batches(test_dataset, test_bl, test_indices, model)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>name</th>\n",
       "      <th>sched_name</th>\n",
       "      <th>prediction</th>\n",
       "      <th>target</th>\n",
       "      <th>real_rank</th>\n",
       "      <th>predicted_rank</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>function436945</td>\n",
       "      <td>function436945_no_schedule</td>\n",
       "      <td>5.212368</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>26.0</td>\n",
       "      <td>16.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>function436945</td>\n",
       "      <td>function436945_schedule_0000</td>\n",
       "      <td>9.486356</td>\n",
       "      <td>3.130280</td>\n",
       "      <td>7.0</td>\n",
       "      <td>8.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>function436945</td>\n",
       "      <td>function436945_schedule_0001</td>\n",
       "      <td>3.436958</td>\n",
       "      <td>1.043359</td>\n",
       "      <td>25.0</td>\n",
       "      <td>25.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>function436945</td>\n",
       "      <td>function436945_schedule_0003</td>\n",
       "      <td>5.027917</td>\n",
       "      <td>1.176245</td>\n",
       "      <td>15.0</td>\n",
       "      <td>17.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>function436945</td>\n",
       "      <td>function436945_schedule_0004</td>\n",
       "      <td>1.015811</td>\n",
       "      <td>0.969065</td>\n",
       "      <td>29.0</td>\n",
       "      <td>27.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>276012</th>\n",
       "      <td>function437145</td>\n",
       "      <td>function437145_schedule_0008</td>\n",
       "      <td>16.478519</td>\n",
       "      <td>1.423987</td>\n",
       "      <td>2.0</td>\n",
       "      <td>3.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>276013</th>\n",
       "      <td>function437145</td>\n",
       "      <td>function437145_schedule_0010</td>\n",
       "      <td>16.717077</td>\n",
       "      <td>1.420506</td>\n",
       "      <td>3.0</td>\n",
       "      <td>1.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>276014</th>\n",
       "      <td>function437145</td>\n",
       "      <td>function437145_schedule_0011</td>\n",
       "      <td>5.570871</td>\n",
       "      <td>0.564614</td>\n",
       "      <td>21.0</td>\n",
       "      <td>22.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>276015</th>\n",
       "      <td>function437145</td>\n",
       "      <td>function437145_schedule_0017</td>\n",
       "      <td>16.538778</td>\n",
       "      <td>1.592543</td>\n",
       "      <td>1.0</td>\n",
       "      <td>2.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>276016</th>\n",
       "      <td>function437145</td>\n",
       "      <td>function437145_schedule_0022</td>\n",
       "      <td>-5.681603</td>\n",
       "      <td>0.081586</td>\n",
       "      <td>32.0</td>\n",
       "      <td>31.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>276017 rows × 6 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "                  name                    sched_name  prediction    target  \\\n",
       "0       function436945    function436945_no_schedule    5.212368  1.000000   \n",
       "1       function436945  function436945_schedule_0000    9.486356  3.130280   \n",
       "2       function436945  function436945_schedule_0001    3.436958  1.043359   \n",
       "3       function436945  function436945_schedule_0003    5.027917  1.176245   \n",
       "4       function436945  function436945_schedule_0004    1.015811  0.969065   \n",
       "...                ...                           ...         ...       ...   \n",
       "276012  function437145  function437145_schedule_0008   16.478519  1.423987   \n",
       "276013  function437145  function437145_schedule_0010   16.717077  1.420506   \n",
       "276014  function437145  function437145_schedule_0011    5.570871  0.564614   \n",
       "276015  function437145  function437145_schedule_0017   16.538778  1.592543   \n",
       "276016  function437145  function437145_schedule_0022   -5.681603  0.081586   \n",
       "\n",
       "        real_rank  predicted_rank  \n",
       "0            26.0            16.0  \n",
       "1             7.0             8.0  \n",
       "2            25.0            25.0  \n",
       "3            15.0            17.0  \n",
       "4            29.0            27.0  \n",
       "...           ...             ...  \n",
       "276012        2.0             3.0  \n",
       "276013        3.0             1.0  \n",
       "276014       21.0            22.0  \n",
       "276015        1.0             2.0  \n",
       "276016       32.0            31.0  \n",
       "\n",
       "[276017 rows x 6 columns]"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test_df"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Spearman_r</th>\n",
       "      <th>nDCG</th>\n",
       "      <th>nDCG_1</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>count</th>\n",
       "      <td>8502.000000</td>\n",
       "      <td>8502.000000</td>\n",
       "      <td>8502.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>mean</th>\n",
       "      <td>0.905679</td>\n",
       "      <td>0.985793</td>\n",
       "      <td>0.948152</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>std</th>\n",
       "      <td>0.097209</td>\n",
       "      <td>0.021263</td>\n",
       "      <td>0.105755</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>min</th>\n",
       "      <td>-0.368012</td>\n",
       "      <td>0.604358</td>\n",
       "      <td>0.058371</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>25%</th>\n",
       "      <td>0.882136</td>\n",
       "      <td>0.984054</td>\n",
       "      <td>0.946073</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>50%</th>\n",
       "      <td>0.936899</td>\n",
       "      <td>0.992794</td>\n",
       "      <td>0.999684</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>75%</th>\n",
       "      <td>0.966228</td>\n",
       "      <td>0.996789</td>\n",
       "      <td>1.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>max</th>\n",
       "      <td>0.995968</td>\n",
       "      <td>0.999972</td>\n",
       "      <td>1.000000</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "        Spearman_r         nDCG       nDCG_1\n",
       "count  8502.000000  8502.000000  8502.000000\n",
       "mean      0.905679     0.985793     0.948152\n",
       "std       0.097209     0.021263     0.105755\n",
       "min      -0.368012     0.604358     0.058371\n",
       "25%       0.882136     0.984054     0.946073\n",
       "50%       0.936899     0.992794     0.999684\n",
       "75%       0.966228     0.996789     1.000000\n",
       "max       0.995968     0.999972     1.000000"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test_df_rank_scores.describe()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "cf_matrix = confusion_matrix(test_df['real_rank'].astype('int32'), test_df['predicted_rank'].astype('int32'))\n",
    "\n",
    "fig = px.imshow(cf_matrix,\n",
    "                labels=dict(x=\"Real rank\", y=\"Predicted rank\", color=\"Number of Schedules (out of 276k)\" ),\n",
    "                x=[str(i) for i in range(1,34)],\n",
    "                y=[str(i) for i in range(1,34)]\n",
    "               )\n",
    "fig.update_xaxes(side=\"top\")\n",
    "fig.show('png') #use fig.show() for interactive mode"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Basic results on the benchmark set"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "loading batches from: /data/scratch/mmerouani/processed_datasets/dataset_Benchmark_batch10.pkl\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████| 3490/3490 [06:20<00:00,  9.18it/s] \n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "GPU memory on cuda:1 nearly full, switching to CPU memory\n",
      "Number of meta batches 3490\n",
      "Data loaded\n",
      "Sizes: (3490, 0) batches\n"
     ]
    }
   ],
   "source": [
    "benchmark_dataset, benchmark_bl, benchmark_indices, _, _ = load_data_meta_batches(benchmark_dataset_file, 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████| 3490/3490 [00:14<00:00, 247.60it/s]\n",
      "100%|██████████| 3435/3435 [03:07<00:00, 18.33it/s]\n"
     ]
    }
   ],
   "source": [
    "benchmark_df, benchmark_df_rank_scores = get_results_df_meta_batches(benchmark_dataset, benchmark_bl, benchmark_indices, model)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Spearman_r</th>\n",
       "      <th>nDCG</th>\n",
       "      <th>nDCG_1</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>count</th>\n",
       "      <td>3435.000000</td>\n",
       "      <td>3435.000000</td>\n",
       "      <td>3435.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>mean</th>\n",
       "      <td>0.678521</td>\n",
       "      <td>0.935988</td>\n",
       "      <td>0.776508</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>std</th>\n",
       "      <td>0.413321</td>\n",
       "      <td>0.072894</td>\n",
       "      <td>0.247141</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>min</th>\n",
       "      <td>-0.976190</td>\n",
       "      <td>0.531952</td>\n",
       "      <td>0.012579</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>25%</th>\n",
       "      <td>0.666667</td>\n",
       "      <td>0.911556</td>\n",
       "      <td>0.644395</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>50%</th>\n",
       "      <td>0.810826</td>\n",
       "      <td>0.967105</td>\n",
       "      <td>0.863074</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>75%</th>\n",
       "      <td>0.910424</td>\n",
       "      <td>0.984400</td>\n",
       "      <td>0.990476</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>max</th>\n",
       "      <td>1.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>1.000000</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "        Spearman_r         nDCG       nDCG_1\n",
       "count  3435.000000  3435.000000  3435.000000\n",
       "mean      0.678521     0.935988     0.776508\n",
       "std       0.413321     0.072894     0.247141\n",
       "min      -0.976190     0.531952     0.012579\n",
       "25%       0.666667     0.911556     0.644395\n",
       "50%       0.810826     0.967105     0.863074\n",
       "75%       0.910424     0.984400     0.990476\n",
       "max       1.000000     1.000000     1.000000"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "benchmark_df_rank_scores.describe()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "pass"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
